home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Unix / CNews / Source / libstdio / rdwr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-10-25  |  2.4 KB  |  113 lines

  1. /*
  2.  * fread and fwrite (optimised version)
  3.  * Could do i/o to/from the user's buffer directly if the transfer is long
  4.  * enough.  If there's a block-aligned block (or more) in the middle, could
  5.  * transfer it directly.
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <string.h>            /* the ANSI one, for memcpy */
  10. #ifndef PTR_TYPE
  11. #define    PTR_TYPE    char *        /* type of _ptr in stdio.h */
  12. #endif
  13.  
  14. #define THRESHOLD 12            /* memcpy vs in-line threshold */
  15.  
  16. typedef unsigned char putc_t;        /* cast putc args to this type */
  17.  
  18. int
  19. fread(ptr, size, count, fp)
  20. char *ptr;
  21. int size, count;
  22. register FILE *fp;
  23. {
  24.     register unsigned bytes = count * size;
  25.     unsigned origbytes = bytes;
  26.  
  27.     while (bytes > 0) {    /* bytes still to be read */
  28.         {
  29.             /* all of bytes in buffer */
  30.             register int copy = fp->_cnt;
  31.  
  32.             if (copy < 0)
  33.                 copy = 0;
  34.             if (copy > bytes)    /* buffer longer than ptr */
  35.                 copy = bytes;    /* only fill ptr */
  36.             bytes -= copy;    /* adjust to reflect next loop */
  37.             fp->_cnt -= copy;
  38.             if (copy < THRESHOLD) {
  39.                 register char *rptr = ptr, *bp = (char *)fp->_ptr;
  40.  
  41.                 for (++copy; --copy > 0; )
  42.                     *rptr++ = *bp++;
  43.                 ptr = rptr;
  44.                 fp->_ptr = (PTR_TYPE)bp;
  45.             } else {
  46.                 memcpy(ptr, (char *)fp->_ptr, copy);
  47.                 ptr += copy;
  48.                 fp->_ptr += copy;
  49.             }
  50.         }
  51.         if (bytes > 0) {    /* more to read, but buffer is empty */
  52.             register int c = getc(fp);    /* refill buffer */
  53.  
  54.             if (c == EOF)
  55.                 break;
  56.             else {
  57.                 *ptr++ = c;
  58.                 --bytes;
  59.             }
  60.         }
  61.     }
  62.     if (size == 0)
  63.         return count;            /* or 0 */
  64.     else
  65.         return (origbytes - bytes) / size;
  66. }
  67.  
  68. int
  69. fwrite(ptr, size, count, fp)
  70. char *ptr;
  71. int size, count;
  72. register FILE *fp;
  73. {
  74.     register unsigned bytes = count * size;
  75.     unsigned origbytes = bytes;
  76.  
  77.     while (bytes > 0) {    /* bytes still to be written */
  78.         {
  79.             register int copy = fp->_cnt;
  80.  
  81.             if (copy < 0)
  82.                 copy = 0;
  83.             if (copy > bytes)    /* buffer longer than ptr */
  84.                 copy = bytes;    /* only empty ptr */
  85.             bytes -= copy;    /* adjust to reflect next loop */
  86.             fp->_cnt -= copy;
  87.             if (copy < THRESHOLD) {
  88.                 register char *rptr = ptr, *bp = (char *)fp->_ptr;
  89.  
  90.                 for (++copy; --copy > 0; )
  91.                     *bp++ = *rptr++;
  92.                 ptr = rptr;
  93.                 fp->_ptr = (PTR_TYPE)bp;
  94.             } else {
  95.                 memcpy((char *)fp->_ptr, ptr, copy);
  96.                 ptr += copy;
  97.                 fp->_ptr += copy;
  98.             }
  99.         }
  100.         if (bytes > 0)    /* more to write, but buffer is full */
  101.             if (putc((putc_t)*ptr, fp) == EOF) /* flush buffer */
  102.                 break;
  103.             else {
  104.                 ptr++;
  105.                 --bytes;
  106.             }
  107.     }
  108.     if (size == 0)
  109.         return count;            /* or 0 */
  110.     else
  111.         return (origbytes - bytes) / size;
  112. }
  113.